//
//  QNPermanentThread.m
//  QNReuseTool
//
//  Created by rsh on 2020/7/15.
//  Copyright © 2020年 rsh. All rights reserved.
//

#import "QNPermanentThread.h"

// MARK: 永久线程保活的工具类

@interface QNPermanentThread ()

@property (nonatomic, strong) NSThread *innerThread;
@property (nonatomic, assign,getter=isStopped) BOOL stopped;
@end

@implementation QNPermanentThread

- (instancetype)init{
    if (self = [super init]) {
        self.stopped = NO;
        
        __weak typeof(self) weakSelf = self;
        
        self.innerThread = [[NSThread alloc] initWithBlock:^{
            //添加一个 Runloop 来线程保活 ==> 往RunLoop中添加source/timer/observer，否则RunLoop中无东西，不会启动。（ NSPort :端口 ）
            [[NSRunLoop currentRunLoop] addPort:[[NSPort alloc] init] forMode:NSDefaultRunLoopMode];
            
            while (weakSelf && !weakSelf.isStopped) {
                // 不能用 [[NSRunLoop currentRunLoop] run] 来启动RunLoop,因为run方法会一直循环执行，永不停止；
                [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
            }
        }];
    }
    return self;
}


-(void)run
{
    [self.innerThread start];
}


- (void)executeTask:(void (^)(void))task
{
    if (!self.innerThread || !task) return;
    
    [self performSelector:@selector(executeXYDTask:) onThread:self.innerThread withObject:nil waitUntilDone:NO];
}


- (void)stop
{
    if (!self.innerThread) return;
    
    // 在结束线程前，要先停止RunLoop
    // waitUntilDone: 传NO ==> 执行该方法的同时，也执行后面的流程；传YES ==> 等该方法执行完后，才执行后面的流程。
    [self performSelector:@selector(stopRunLoop) onThread:self.innerThread withObject:nil waitUntilDone:YES];
}


// MARK: 对象销毁时，自己调用stop方法，停止RunLoop
- (void)dealloc{
    NSLog(@"%s",__func__);
    [self stop];
}


// MARK: 停止RunLoop
-(void)stopRunLoop
{
    self.stopped = YES; // 更改标记位
    CFRunLoopStop(CFRunLoopGetCurrent()); // 停止当前RunLoop
    self.innerThread = nil;    // 线程执空
}


// MARK: 执行相应的任务
- (void)executeXYDTask:(void (^)(void))task
{
    task();
}




@end
